#pragma once

#include <iostream>
#include <string>
//用“ ”和“\n”表示协议的具体规定
const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";

//添加报头：将数据长度作为报头内容，并用\n分隔开来
//（“len”\n"x op y"\n）
std::string Encode(std::string &content)
{
    std::string package = std::to_string(content.size());
    package += protocol_sep;
    package += content;
    package += protocol_sep;

    return package;
}
//根据报头内容以及\n，去掉报头，从而拿到数据本身
bool Decode(std::string &package, std::string *content)
{
    std::size_t pos = package.find(protocol_sep);
    if (pos == std::string::npos)//数据不完整，返回
        return false;
    std::string len_str = package.substr(0, pos);
    std::size_t len = std::stoi(len_str);
    std::size_t total_len = len_str.size() + len + 2;
    if (package.size() < total_len)//数据不完整，返回
        return false;

    *content = package.substr(pos + 1, len);
    // 走到此次说明数据正确被取出，因此package里的数据可以清空
    package.erase(0, total_len);

    return true;
}

class Request
{
public:
    Request(int data1, int data2, char oper) 
    : x(data1), y(data2), op(oper)
    {
    }
    Request()
    {
    }

public:
    bool Serialize(std::string *out)//序列化
    {
        // struct => string, "x op y"
        //根据协议的规定进行序列化
        std::string s = std::to_string(x);
        s += blank_space_sep;
        s += op;
        s += blank_space_sep;
        s += std::to_string(y);
        *out = s;
        return true;
    }
    bool Deserialize(const std::string &in) //反序列化
    {
        //根据协议的规定拿到有效数据
        std::size_t left = in.find(blank_space_sep);
        if (left == std::string::npos)
            return false;
        std::string part_x = in.substr(0, left);

        std::size_t right = in.rfind(blank_space_sep);
        if (right == std::string::npos)
            return false;
        std::string part_y = in.substr(right + 1);
        if (left + 2 != right)
            return false;
        //添加到当前的成员变量中
        op = in[left + 1];
        x = std::stoi(part_x);
        y = std::stoi(part_y);
        return true;
    }
    void DebugPrint()
    {
        std::cout << "新请求构建完成:  " << x << op << y << "=?" 
        << std::endl;
    }

public:
    // x op y
    int x;
    int y;
    char op; // + - * / %
};